package config

import (
	"context"
	"strings"

	"github.com/glennliao/apijson-go/consts"
	"github.com/glennliao/apijson-go/model"
	"github.com/glennliao/apijson-go/util"
	"github.com/gogf/gf/v2/container/gvar"
)

type C操作配置 struct {
	Q请求配置     *Q请求配置集合
	F访问控制     *F访问控制
	H函数集合     *H函数集合
	Z主键生成函数映射 map[string]RowKeyGenerator
	M默认角色函数   M默认角色函数
}

func (配置 *C操作配置) S是否跳过验证() bool {
	return 配置.F访问控制.J禁用验证
}

func (配置 *C操作配置) H获取默认角色函数() M默认角色函数 {
	return 配置.M默认角色函数
}

func (配置 *C操作配置) H获取访问配置(键 string, 不验证 bool) (*F访问配置结构, error) {
	return 配置.F访问控制.H获取访问配置(键, 不验证)
}

func (配置 *C操作配置) H获取函数(名称 string) *H函数定义 {
	return 配置.H函数集合.H函数映射[名称]
}

func (配置 *C操作配置) T调用函数(ctx context.Context, 名称 string, 参数 model.Map) (结果 any, 错误 error) {
	return 配置.H函数集合.T调用函数(ctx, 名称, 参数)
}

func (配置 *C操作配置) H获取请求配置(标签 string, 方法 string, 版本 string) (*Q请求配置, error) {
	return 配置.Q请求配置.H获取请求配置(标签, 方法, 版本)
}

func (配置 *C操作配置) Z执行条件函数(ctx context.Context, 请求 T条件请求, 条件 *T条件结果) error {
	return 配置.F访问控制.T条件处理函数(ctx, 请求, 条件)
}

func (配置 *C操作配置) S生成主键(ctx context.Context, 生成函数名 string, 访问名称 string, 表名 string, 数据 model.Map) (model.Map, error) {

	var 参数键列表 []string

	if strings.Contains(生成函数名, "(") {
		生成函数名, 参数键列表 = util.J解析函数字符串(生成函数名)
	}

	if 函数, 存在 := 配置.Z主键生成函数映射[生成函数名]; 存在 {

		请求 := &H行键生成请求{
			F访问名称: 访问名称,
			B表名:   表名,
			S数据:   数据,
		}

		if len(参数键列表) > 0 {
			var 参数 = model.FuncParam{}
			for 索引, 项 := range 函数.C参数列表 {
				if len(参数键列表) >= 索引 {
					参数[项.M名称] = gvar.New(参数键列表[索引])
				} else {
					参数[项.M名称] = gvar.New(项.M默认值)
				}
			}
			请求.S生成参数 = 参数
		}

		结果 := X新建行键生成结果()
		错误 := 函数.C处理函数(ctx, 请求, 结果)
		return 结果.S数据, 错误
	}

	return nil, consts.X新建系统错误("主键生成器未找到：" + 生成函数名)
}
